home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / fifo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  4.0 KB  |  164 lines

  1. /*
  2.  *  linux/fs/fifo.c
  3.  *
  4.  *  written by Paul H. Hargrove
  5.  *
  6.  * This file is subject to the terms and conditions of the GNU General Public
  7.  * License.  See the file README.legal in the main directory of this archive
  8.  * for more details.
  9.  */
  10.  
  11. #include <linux/sched.h>
  12. #include <linux/kernel.h>
  13. #include <linux/errno.h>
  14. #include <linux/fcntl.h>
  15.  
  16. static int fifo_open(struct inode * inode,struct file * filp)
  17. {
  18.     int retval = 0;
  19.     unsigned long page;
  20.  
  21.     switch( filp->f_mode ) {
  22.  
  23.     case 1:
  24.     /*
  25.      *  O_RDONLY
  26.      *  POSIX.1 says that O_NONBLOCK means return with the FIFO
  27.      *  opened, even when there is no process writing the FIFO.
  28.      */
  29.         filp->f_op = &connecting_fifo_fops;
  30.         if (!PIPE_READERS(*inode)++)
  31.             wake_up(&PIPE_WRITE_WAIT(*inode));
  32.         if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
  33.             PIPE_RD_OPENERS(*inode)++;
  34.             while (!PIPE_WRITERS(*inode)) {
  35.                 if (current->signal & ~current->blocked) {
  36.                     retval = -ERESTARTSYS;
  37.                     break;
  38.                 }
  39.                 interruptible_sleep_on(&PIPE_READ_WAIT(*inode));
  40.             }
  41.             if (!--PIPE_RD_OPENERS(*inode))
  42.                 wake_up(&PIPE_WRITE_WAIT(*inode));
  43.         }
  44.         while (PIPE_WR_OPENERS(*inode))
  45.             interruptible_sleep_on(&PIPE_READ_WAIT(*inode));
  46.         if (PIPE_WRITERS(*inode))
  47.             filp->f_op = &read_fifo_fops;
  48.         if (retval && !--PIPE_READERS(*inode))
  49.             wake_up(&PIPE_WRITE_WAIT(*inode));
  50.         break;
  51.     
  52.     case 2:
  53.     /*
  54.      *  O_WRONLY
  55.      *  POSIX.1 says that O_NONBLOCK means return -1 with
  56.      *  errno=ENXIO when there is no process reading the FIFO.
  57.      */
  58.         if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
  59.             retval = -ENXIO;
  60.             break;
  61.         }
  62.         filp->f_op = &write_fifo_fops;
  63.         if (!PIPE_WRITERS(*inode)++)
  64.             wake_up(&PIPE_READ_WAIT(*inode));
  65.         if (!PIPE_READERS(*inode)) {
  66.             PIPE_WR_OPENERS(*inode)++;
  67.             while (!PIPE_READERS(*inode)) {
  68.                 if (current->signal & ~current->blocked) {
  69.                     retval = -ERESTARTSYS;
  70.                     break;
  71.                 }
  72.                 interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
  73.             }
  74.             if (!--PIPE_WR_OPENERS(*inode))
  75.                 wake_up(&PIPE_READ_WAIT(*inode));
  76.         }
  77.         while (PIPE_RD_OPENERS(*inode))
  78.             interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
  79.         if (retval && !--PIPE_WRITERS(*inode))
  80.             wake_up(&PIPE_READ_WAIT(*inode));
  81.         break;
  82.     
  83.     case 3:
  84.     /*
  85.      *  O_RDWR
  86.      *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
  87.      *  This implementation will NEVER block on a O_RDWR open, since
  88.      *  the process can at least talk to itself.
  89.      */
  90.         filp->f_op = &rdwr_fifo_fops;
  91.         if (!PIPE_READERS(*inode)++)
  92.             wake_up(&PIPE_WRITE_WAIT(*inode));
  93.         while (PIPE_WR_OPENERS(*inode))
  94.             interruptible_sleep_on(&PIPE_READ_WAIT(*inode));
  95.         if (!PIPE_WRITERS(*inode)++)
  96.             wake_up(&PIPE_READ_WAIT(*inode));
  97.         while (PIPE_RD_OPENERS(*inode))
  98.             interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
  99.         break;
  100.  
  101.     default:
  102.         retval = -EINVAL;
  103.     }
  104.     if (retval || PIPE_BASE(*inode))
  105.         return retval;
  106.     page = __get_free_page(GFP_KERNEL);
  107.     if (PIPE_BASE(*inode)) {
  108.         free_page(page);
  109.         return 0;
  110.     }
  111.     if (!page)
  112.         return -ENOMEM;
  113.     PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
  114.     PIPE_BASE(*inode) = (char *) page;
  115.     return 0;
  116. }
  117.  
  118. /*
  119.  * Dummy default file-operations: the only thing this does
  120.  * is contain the open that then fills in the correct operations
  121.  * depending on the access mode of the file...
  122.  */
  123. static struct file_operations def_fifo_fops = {
  124.     NULL,
  125.     NULL,
  126.     NULL,
  127.     NULL,
  128.     NULL,
  129.     NULL,
  130.     NULL,
  131.     fifo_open,        /* will set read or write pipe_fops */
  132.     NULL,
  133.     NULL
  134. };
  135.  
  136. static struct inode_operations fifo_inode_operations = {
  137.     &def_fifo_fops,        /* default file operations */
  138.     NULL,            /* create */
  139.     NULL,            /* lookup */
  140.     NULL,            /* link */
  141.     NULL,            /* unlink */
  142.     NULL,            /* symlink */
  143.     NULL,            /* mkdir */
  144.     NULL,            /* rmdir */
  145.     NULL,            /* mknod */
  146.     NULL,            /* rename */
  147.     NULL,            /* readlink */
  148.     NULL,            /* follow_link */
  149.     NULL,            /* bmap */
  150.     NULL,            /* truncate */
  151.     NULL            /* permission */
  152. };
  153.  
  154. void init_fifo(struct inode * inode)
  155. {
  156.     inode->i_op = &fifo_inode_operations;
  157.     inode->i_pipe = 1;
  158.     PIPE_BASE(*inode) = NULL;
  159.     PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
  160.     PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
  161.     PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
  162.     PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
  163. }
  164.